package questions

import (
	"context"
	"reflect"
)

const (
	// TableQuestions SQLite中题目表的名称
	TableQuestions = "questions"
)

// QuestionTemplate 题目模板，包含所有题型的组合
type QuestionTemplate struct {
	SingleChoiceQuestion   *SingleChoiceQuestion   `json:"singleChoice,omitempty"`   // 单选题
	MultipleChoiceQuestion *MultipleChoiceQuestion `json:"multipleChoice,omitempty"` // 多选题
	FillBlankQuestion      *FillBlankQuestion      `json:"fillBlank,omitempty"`      // 填空题
	TrueFalseQuestion      *TrueFalseQuestion      `json:"trueFalse,omitempty"`      // 判断题
	ShortAnswerQuestion    *ShortAnswerQuestion    `json:"shortAnswer,omitempty"`    // 简答题
	RatingQuestion         *RatingQuestion         `json:"rating,omitempty"`         // 评分题
}

// IsEmpty 使用反射检查是否为空
func (t *QuestionTemplate) IsEmpty() bool {
	val := reflect.ValueOf(t).Elem()
	for i := range make([]struct{}, val.NumField()) {
		if !val.Field(i).IsNil() {
			return false
		}
	}
	return true
}

// QuestionRepository 题目仓储接口
// 定义对题目的存储和检索操作, 具体实现在repository层
type QuestionRepository interface {
	// GetQuestionTemplates 获取题目模板
	GetQuestionTemplates(ctx context.Context, types []QuestionType) (QuestionTemplate, error)

	// 添加、更新、删除题目的方法
	CreateQuestion(ctx context.Context, template *QuestionTemplate) error
	UpdateQuestion(ctx context.Context, questionID string) error
	DeleteQuestion(ctx context.Context, questionID string) error
	GetQuestionByID(ctx context.Context, questionID string) (any, error)
	ListQuestions(ctx context.Context) ([]any, error)
}

// QuestionService 题目用例接口
// 定义题目相关的业务逻辑操作, 是应用服务层对领域模型行为的封装
type QuestionService interface {
	// GetQuestionTemplates 获取题目模板
	GetQuestionTemplates(ctx context.Context, types []QuestionType) (QuestionTemplate, error)

	// 业务层操作方法
	CreateQuestion(ctx context.Context, template *QuestionTemplate) error
	UpdateQuestion(ctx context.Context, questionID string) error
	DeleteQuestion(ctx context.Context, questionID string) error
	GetQuestionByID(ctx context.Context, questionID string) (any, error)
	ListQuestions(ctx context.Context) ([]any, error)
}
